import http from "./http";
import { ipcMain } from "electron";
import X2Js from "x2js";
import {
  getSpc,
  tagReportedSpc,
  deleteExpireSpc,
  delByUuids,
  getAnomaly,
  tagReportedAnomaly,
  deleteExpireAnomaly
} from "../database/db";
import log from "electron-log";

let autoReportTimer = null;

const x2js = new X2Js();

function catchResult(e, tag = undefined) {
  const res = e.response;
  if (e.code === "ETIMEDOUT" || e.code === "ENETUNREACH" || e.code === "EHOSTUNREACH") {
    return {
      code: 97,
      msg: "网络异常，请检查右下角网络连接是否正常！"
    };
  }
  log.error(e.response ?? e);
  if (res && res.status === 422) {
    return {
      code: 98,
      msg: `${tag}请求参数错误`,
      data: res.data.detail
    };
  } else {
    return {
      code: 99,
      msg: `未知错误：${tag}获取失败！请联系管理员查看`,
      data: e.code
    };
  }
}

export async function login(username) {
  try {
    const res = await http.get("http://172.75.200.104/api/v2/Hr/GetUser", {
      params: { userid: username }
    });
    if (res.status === 200) {
      const user = res.data.data?.user;
      if (user) {
        let identity = 0;
        const identityDesc = user["所属岗位"];
        const belong = user["所属部门名称"];
        if (identityDesc === "质量技术员" || belong.includes("质量控制部")) identity = 2;
        else if (identityDesc === "生产班长") identity = 1;
        return {
          code: 0,
          msg: "success",
          data: {
            username: user["员工编号"],
            realname: user["员工姓名"],
            identity: identity
          }
        };
      } else {
        return {
          code: 2,
          msg: "无法获取用户信息，查无用户，请联系管理员解决异常！",
          data: res.data
        };
      }
    } else {
      return {
        code: 3,
        msg: "无法获取用户信息，请求状态异常，请联系管理员解决异常！",
        data: res.data
      };
    }
  } catch (e) {
    return catchResult(e, "用户信息");
  }
}

export async function getWorkCenters() {
  const url = "http://172.80.10.63/A-LDMesService/ExecutionService.asmx?wsdl";
  const headers = { "Content-Type": "text/xml; charset=utf-8" };
  const body = (workSiteId) => `<?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    >
      <soap:Body>
        <GetWorkCenterByWorkSite xmlns="http://tempuri.org/">
          <workSiteID>${workSiteId}</workSiteID>
        </GetWorkCenterByWorkSite>
      </soap:Body>
    </soap:Envelope>`;
  try {
    const res = await http.post(url, body(256315), { headers });
    if (res.status === 200) {
      const data = x2js.xml2js(res.data);
      const xmlDoc =
        data.Envelope.Body.GetWorkCenterByWorkSiteResponse.GetWorkCenterByWorkSiteResult.diffgram
          .DocumentElement.WorkCenter;
      return {
        code: 0,
        msg: "success",
        data: xmlDoc
      };
    } else {
      return {
        code: 0,
        msg: `生产信息获取失败：${res.status}`,
        data: res.data
      };
    }
  } catch (e) {
    return catchResult(e, "用户信息");
  }
}

export async function getProcessInfo(workCenterType, templateId) {
  try {
    const res = await http.get("/spc/client/template", {
      params: { workCenterType: workCenterType, template: templateId }
    });
    if (res.status === 200) {
      return {
        code: 0,
        msg: res.data.msg,
        data: res.data.data ? res.data.data : res.data
      };
    } else {
      return {
        code: 1,
        msg: res.data.msg,
        data: res.data.data
      };
    }
  } catch (e) {
    return catchResult(e, "岗位信息");
  }
}

async function getTechnicParams(processId, modelCode) {
  try {
    const res = await http.get("/process/bind/ser", {
      params: { position_id: processId, material_code: modelCode }
    });
    if (res.status === 200) {
      return {
        code: 0,
        msg: "success",
        data: res.data.t_query
      };
    } else {
      return {
        code: 1,
        msg: "工艺要求获取失败，错误码：" + res.status,
        data: res.data
      };
    }
  } catch (e) {
    return catchResult(e, "工艺要求");
  }
}

async function getModelShortCode(modelCode) {
  try {
    const res = await http.get("/process/short_code", {
      params: { material_code: modelCode }
    });
    if (res.status === 200) {
      return {
        code: 0,
        msg: "success",
        data: res.data.data.short_code
      };
    } else {
      return {
        code: 1,
        msg: "零件字码获取失败，错误码：" + res.status,
        data: res.data
      };
    }
  } catch (e) {
    return catchResult(e, "零件字码");
  }
}

async function getModelByPartCodes(partCodes) {
  const url = "http://172.80.10.63/A-LDMesService/ExecutionService.asmx?wsdl";
  const headers = { "Content-Type": "text/xml; charset=utf-8" };
  const body = (partCode) => `<?xml version="1.0" encoding="utf-8"?>
                <soap:Envelope
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
                >
                  <soap:Body>
                    <GetPartByPartCode xmlns="http://tempuri.org/">
                      <partCode>${partCode}</partCode>
                    </GetPartByPartCode>
                  </soap:Body>
                </soap:Envelope>`;
  let data = null;
  try {
    data = await http.all(
      partCodes.map((partCode) => {
        return http.post(url, body(partCode), {
          headers: headers
        });
      })
    );
  } catch (e) {
    return catchResult(e, "零件型号");
  }
  try {
    const resultMap = {};
    data.forEach((d) => {
      if (d.status === 200) {
        const parse = x2js.xml2js(d.data);
        const document =
          parse.Envelope.Body.GetPartByPartCodeResponse.GetPartByPartCodeResult.diffgram
            .DocumentElement.Part;
        resultMap[document.PartCode] = {
          partCode: document.PartCode,
          partName: document.PartName
        };
      }
    });
    const result = [];
    for (const key in resultMap) {
      result.push(resultMap[key]);
    }
    return {
      code: 0,
      msg: "success",
      data: result
    };
  } catch (e) {
    console.log(e);
    return {
      code: 97,
      msg: "零件型号数据处理异常",
      data: JSON.stringify(e)
    };
  }
}

async function getPartModelList(workcentid) {
  try {
    const res = await http.get("http://172.75.200.104:7079/api/Report/Get_productionInfos", {
      params: { status: 3, workcentid: workcentid }
    });
    if (res.status === 200) {
      const data = res.data.data?.data;
      const partCodes = [];
      for (const d of data) {
        partCodes.push(d.partcode);
      }
      return await getModelByPartCodes(partCodes);
    } else {
      return {
        code: 2,
        msg: "无法获取订单信息！请联系管理员解决异常！",
        data: res.data
      };
    }
  } catch (e) {
    return catchResult(e, "零件型号");
  }
}

async function getPartModelMap(partCodes) {
  try {
    const res = await http.post("http://172.80.10.150:7000/api/v1/process/material/getName/", {
      codes: partCodes
    });
    return res.data;
  } catch (e) {
    return catchResult(e, "根据物料编码获取零件名称");
  }
}

async function reportDetectionData(dataList) {
  try {
    const res = await http.post("/spc/report", dataList);
    return res.data;
  } catch (e) {
    return catchResult(e, "点检数据上报");
  }
}

// 上报打点异常信息
async function reportAnomaly(workCenterId, content, username) {
  try {
    const res = await http.post("http://172.80.10.150:2107/api/anomaly/", {
      classId: 12,
      workCenterId,
      content,
      initiatorType: 2,
      initiator: username
    });
    if (res.status === 200) {
      if (res.code === 200) {
        return {
          code: 0,
          msg: "success",
          data: res.data
        };
      } else {
        return {
          code: 2,
          msg: res.msg,
          data: res.data
        };
      }
    } else {
      return {
        code: 2,
        msg: "异常上报失败",
        data: res.data
      };
    }
  } catch (e) {
    return catchResult(e, "打点异常提报");
  }
}

async function delDetectionData(uuid) {
  try {
    const res = await http.delete("/spc/report", {
      params: { uuid }
    });
    return res.data;
  } catch (e) {
    return catchResult(e, "删除数据");
  }
}

async function startAutoPostDetection(flag) {
  // return;
  if (flag) {
    if (autoReportTimer) {
      return;
    }
    autoReportTimer = setInterval(async () => {
      try {
        // 找出未上报的点检数据进行上报
        let neverReports = await getSpc(
          undefined,
          undefined,
          undefined,
          undefined,
          undefined,
          false
        );
        if (neverReports.length && neverReports.length > 0) {
          // 查找异常uuid的数据，直接删除
          const errUuids = [];
          for (let i = 0; i < neverReports.length; i++) {
            const item = neverReports[i];
            if (item.uuid.length > 64) {
              errUuids.push(item.uuid);
            }
          }
          if (errUuids.length > 0) {
            await delByUuids(errUuids);
            // 重新查询未上报的数据
            neverReports = await getSpc(
              undefined,
              undefined,
              undefined,
              undefined,
              undefined,
              false
            );
          }
          const res = await reportDetectionData(neverReports);
          if (res.code < 10) {
            await tagReportedSpc(res.data);
          }
        }
        // 删除过期的已上报的点检数据
        await deleteExpireSpc();
        // 找出未上报的异常进行上报
        const neverReportAnomaly = await getAnomaly(
          undefined,
          undefined,
          undefined,
          undefined,
          false
        );
        if (neverReportAnomaly.length && neverReportAnomaly.length > 0) {
          for (const anomaly of neverReportAnomaly) {
            const content = `${anomaly.processName}工序在${anomaly.time}时段因 ${anomaly.content} 影响点检工作进行`;
            const res = await reportAnomaly(anomaly.workCenterId, content, anomaly.reporter);
            if (res.code < 10) {
              await tagReportedAnomaly(anomaly.id);
            }
          }
        }
        // 删除过期且已上报的异常数据
        await deleteExpireAnomaly();
      } catch (e) {
        console.log("report error: ", e);
      }
    }, 10 * 1000);
  } else {
    if (!autoReportTimer) {
      return;
    }
    clearInterval(autoReportTimer);
    autoReportTimer = null;
  }
}

async function getUserIdByCardNumber(cardNumber) {
  try {
    const res = await http.get("http://172.75.200.104:7079/api/SysSetting/get_User", {
      params: { cardnumber: cardNumber }
    });
    if (res.status === 200) {
      const user = res.data.data?.data;
      if (user.length === 0) {
        return {
          code: 1,
          msg: `员工<${cardNumber}>工卡未登记`
        };
      }
      return {
        code: 0,
        msg: "success",
        data: user[0].loginname
      };
    } else {
      return {
        code: 2,
        msg: "获取工卡相关信息失败！请联系管理员解决异常！",
        data: res.data
      };
    }
  } catch (e) {
    return catchResult(e, "工卡");
  }
}

export function initRequestIpc() {
  ipcMain.handle("http-login", async (e, username) => {
    return await login(username);
  });
  ipcMain.handle("http-get-workcenters", async () => {
    return await getWorkCenters();
  });
  ipcMain.handle("http-get-process", async (e, workCenterType, templateId) => {
    return await getProcessInfo(workCenterType, templateId);
  });
  ipcMain.handle("http-get-technic-params", async (e, processId, modelCode) => {
    return await getTechnicParams(processId, modelCode);
  });
  ipcMain.handle("http-get-partmodels", async (e, workCenterId) => {
    return await getPartModelList(workCenterId);
  });
  ipcMain.handle("http-get-partmodel-map", async (e, partCodes) => {
    return await getPartModelMap(partCodes);
  });
  ipcMain.handle("http-del-detection", async (e, uuid) => {
    return await delDetectionData(uuid);
  });
  ipcMain.handle("http-card2userid", async (e, cardNumber) => {
    return await getUserIdByCardNumber(cardNumber);
  });
  ipcMain.handle("http-get-short-code", async (e, modelCode) => {
    return await getModelShortCode(modelCode);
  });
  ipcMain.on("http-auto-post-detection", async (e, flag) => {
    return await startAutoPostDetection(flag);
  });
  ipcMain.on("http-report-anomaly", async (e, workCenterId, content, username) => {
    return await reportAnomaly(workCenterId, content, username);
  });
}
